﻿using FastDFS.Client;
using System;
using System.IO;
using System.Web;
using up6.db.store;
using up6.db.utils;
using up6.utils;

namespace api.down2
{
    public partial class f_down : WebBase
    {
        string id = string.Empty;
        string blockIndex = string.Empty;
        string blockOffset = string.Empty;
        string blockSize = string.Empty;
        string pathSvr = string.Empty;
        string object_key = string.Empty;

        bool check_params(params string[] vs)
        {
            foreach(string v in vs)
            {
                if (String.IsNullOrEmpty(v)) return false;
            }
            return true;
        }

        protected void Page_Load(object sender, EventArgs e)
        {
            this.id           = this.headString("id");//文件id
            this.blockIndex   = this.headString("blockIndex");//基于1
            this.blockOffset  = this.headString("blockOffset");//块偏移，相对于整个文件
            this.blockSize    = this.headString("blockSize");//块大小（当前需要下载的）
            this.pathSvr      = this.headString("pathSvr");//文件在服务器的位置
            this.object_key = this.headString("object_key");//
            pathSvr             = HttpUtility.UrlDecode(pathSvr);

            if ( !this.check_params(id,blockIndex,blockOffset,pathSvr))
            {
                Response.StatusCode = 500;
                return;
            }

            try
            {
                Response.ContentType = "application/octet-stream";
                Response.AddHeader("Content-Length", blockSize);
                var store = ConfigReader.storage();
                if (store == StorageType.FastDFS) this.FastDFS_down();
                else if (store == StorageType.Minio ||
                    store == StorageType.OSS ||
                    store == StorageType.OBS)
                { 
                    this.minio_down(); 
                }
                else this.io_down();
            }
            catch (Exception ex)
            {
                Response.StatusCode = 500;
                Response.Write("Error : " + ex.Message);
            }
        }

        void io_down() {
            //文件不存在
            if(!File.Exists(this.pathSvr))
            {
                Response.StatusCode = 500;
                Response.Write("file not exist path:" + this.pathSvr);
                return;
            }
            var br = ConfigReader.blockReader();
            WebWriter ww = new WebWriter();
            ww.write(br, Response, this.pathSvr, long.Parse(this.blockOffset), int.Parse(blockSize));
        }

        void minio_down()
        {
            var br = ConfigReader.blockReader();
            WebWriter ww = new WebWriter();
            ww.write(br, Response, this.object_key, long.Parse(this.blockOffset), int.Parse(blockSize));
        }

        void FastDFS_down()
        {
            var reader = ConfigReader.blockReader();
            long end = long.Parse(this.blockSize);
            long offset = long.Parse(this.blockOffset);
            end += offset;//size转换成相对于整个文件
            FastDFSTool fdt = new FastDFSTool();
            var node = fdt.node();

            //大于1KB，必须使用流方式下载
            long len = 1024;//每次取1KB的数据
            if (end > len)
            {
                while (len > 0&& Response.IsClientConnected)
                {
                    var buf = FastDFSClient.DownloadFile(node, this.object_key, offset, len);
                    Response.OutputStream.Write(buf, 0, buf.Length);
                    Response.Flush();
                    offset += len;
                    len = (end - offset) > len ? len : (end - offset);
                }
            }//小于1KB，直接下载
            else
            {
                var buf = FastDFSClient.DownloadFile(fdt.node(), this.object_key);
                Response.OutputStream.Write(buf, 0, buf.Length);
                Response.Flush();
            }
        }
    }
}